package com.yb.xczx.cloud.auth.filter;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yb.core.constant.RedisKeyConstant;
import com.yb.core.constant.ServletRequestConstant;
import com.yb.core.enums.LoginTypeEnum;
import com.yb.core.model.XczxLoginUser;
import com.yb.core.util.XczxTokenGenerator;
import com.yb.xczx.cache.manager.api.XczxCacheManager;
import com.yb.xczx.cache.manager.api.XczxStringCacheManager;
import com.yb.xczx.cloud.auth.bean.XczxAbstractAuthenticationToken;
import com.yb.xczx.cloud.auth.bean.XczxSysUser;
import com.yb.xczx.cloud.auth.bean.XczxUserPassAuthenticationToken;
import com.yb.xczx.cloud.auth.entity.SysUser;
import com.yb.xczx.cloud.auth.handler.LoginSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.log.LogMessage;
import org.springframework.lang.Nullable;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.*;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.context.NullSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Copyright (C), 2022-2023, 姚兵
 * Author: 32210
 * Date: 2023/5/17 16:02
 * FileName: XczxTokenAuthenticationFilter
 * Description:
 */

public class XczxUserPassAuthenticationFilter extends XczxAbstractAuthenticationProcessingFilter {

    private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/login",
            "POST");


    private boolean postOnly = true;


    public XczxUserPassAuthenticationFilter() {
        super(DEFAULT_ANT_PATH_REQUEST_MATCHER);
    }


    @Autowired
    XczxStringCacheManager xczxStringCacheManager;
    public XczxUserPassAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(DEFAULT_ANT_PATH_REQUEST_MATCHER, authenticationManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
        if (this.postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }
        XczxLoginUser xczxLoginUser = (XczxLoginUser) request.getAttribute(ServletRequestConstant.XCZX_LOGIN_USER);

        String username = xczxLoginUser.getUsername();
        username = (username != null) ? username.trim() : "";
        String password = xczxLoginUser.getPassword();
        password = (password != null) ? password : "";
        SysUser sysUser = new SysUser();
        sysUser.setUsername(username);
        sysUser.setPassword(password);
        XczxSysUser xczxSysUser = new XczxSysUser(sysUser);
        XczxUserPassAuthenticationToken authRequest = XczxUserPassAuthenticationToken.unauthenticated(xczxSysUser);
        // Allow subclasses to set the "details" property
        setDetails(request, authRequest);
        return this.getAuthenticationManager().authenticate(authRequest);
    }



    protected void setDetails(HttpServletRequest request, XczxAbstractAuthenticationToken authRequest) {
        authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
    }



    public void setPostOnly(boolean postOnly) {
        this.postOnly = postOnly;
    }


    @Override
    protected String loginType() {
        return LoginTypeEnum.USER_PASS.getLoginType();
    }
}
